package khs.java_mic_rtp.main.java;

import gov.nist.jrtp.RtpException;
import gov.nist.jrtp.RtpManager;
import gov.nist.jrtp.RtpPacket;
import gov.nist.jrtp.RtpSession;

import java.io.IOException;
import java.net.SocketException;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.TargetDataLine;

/**
 * Hello world!
 *
 */
public class App 
{
    private static final int FRAMES_PER_BUFFER = 1024;
    
    public static void main( String[] args ) throws Exception
    {
        new App().playAudio();
    }
    
    private  AudioFormat getAudioFormat(){
        float sampleRate = 44100.0F;
        //8000,11025,16000,22050,44100
        int sampleSizeInBits = 16;
        //8,16
        int channels = 1;
        //1,2
        boolean signed = true;
        //true,false
        boolean bigEndian = false;
        //true,false
        return new AudioFormat(sampleRate,
                               sampleSizeInBits,
                               channels,
                               signed,
                               bigEndian);
      }//end getAudioFormat
    
    public void playAudio() throws Exception {
        AudioFormat audioFormat;
        TargetDataLine targetDataLine;
    
        audioFormat = getAudioFormat();
        DataLine.Info dataLineInfo =
        new DataLine.Info(
                  TargetDataLine.class,
                  audioFormat);
        targetDataLine = (TargetDataLine) AudioSystem.getLine(dataLineInfo);

        /*
        Line.Info lines[] = AudioSystem.getTargetLineInfo(dataLineInfo);
        for (int n = 0; n < lines.length; n++) {
            System.out.println("Target " + lines[n].toString() + " " + lines[n].getLineClass());
        }
        targetDataLine = (TargetDataLine)
            AudioSystem.getLine(lines[0]);
        */
    
        targetDataLine.open(audioFormat, 
                audioFormat.getFrameSize() * FRAMES_PER_BUFFER);
        targetDataLine.start();
    
        rtpAudioStream(new AudioInputStream(targetDataLine));

    /*
    File soundFile = new File( fileName );
     
    try {
        // Create a stream from the given file.
        // Throws IOException or UnsupportedAudioFileException
        AudioInputStream audioInputStream = AudioSystem.getAudioInputStream( soundFile );
        // AudioSystem.getAudioInputStream( inputStream ); // alternate audio stream from inputstream
        playAudioStream( audioInputStream );
    } catch ( Exception e ) {
        System.out.println( "Problem with file " + fileName + ":" );
        e.printStackTrace();
    }
    */
    } // playAudioFile
    
    /** Plays audio from the given audio input stream. 
     * @throws IOException 
     * @throws SocketException 
     * @throws RtpException */
    public void rtpAudioStream( AudioInputStream audioInputStream ) throws SocketException, IOException, RtpException {
        RtpManager rtpManager = new RtpManager("127.0.0.1");
        RtpSession rtpSession = rtpManager.createRtpSession(10001, "127.0.0.1", 10000);
        
        int bufferSize = RtpPacket.MAX_PAYLOAD_BUFFER_SIZE;
        RtpPacket rtpPacket = new RtpPacket();
        rtpPacket.setV(2);
        rtpPacket.setP(1);
        rtpPacket.setX(1);
        rtpPacket.setCC(1);
        rtpPacket.setM(1);
        rtpPacket.setPT(8);
        //rtpPacket.setTS(1);
        rtpPacket.setSSRC(1);
        
        byte [] buffer = new byte[ bufferSize - RtpPacket.FIXED_HEADER_LENGTH];
 
        // Move the data until done or there is an error.
        long currentTime = System.currentTimeMillis();
        try {
            int bytesRead = 0;
            while ( bytesRead >= 0 ) {
                bytesRead = audioInputStream.read( buffer, 0, buffer.length );
                if ( bytesRead >= 0 ) {
//                        Set RTP packet data rather than create new RTP packet
                    rtpPacket.setTS(System.currentTimeMillis() - currentTime);
                    
                    rtpPacket.setPayload(buffer, bytesRead);
                    rtpSession.sendRtpPacket(rtpPacket);
                }
            } // while
        } catch ( IOException e ) {
            e.printStackTrace();
        }
    } // playAudioStream
}
